#pragma once

#include "DeviceStub.h"
#include <windows.h>
#include "IPainter.h"

namespace sol9
{
	namespace graphics
	{
		class IImage;
		class IPainter;
		class IRenderer;
	}

namespace device
{

	class DeviceWin32;

	struct SDeviceMap
	{
		HWND hWnd;
		DeviceWin32* pDevice;

		SDeviceMap(HWND _hWnd, DeviceWin32* _pDevice)
			: hWnd(_hWnd), pDevice(_pDevice) {}
	};

	typedef std::list<SDeviceMap> DeviceMapList;
	typedef DeviceMapList::iterator DeviceMapIterator;

	class DeviceWin32 : public DeviceStub
	{
		__declareClass(DeviceWin32);

	private:
		HWND m_hWnd;
		static std::map<UINT, eMouseInputEvent> s_mapMouseMessage;
		static DeviceMapList s_listDeviceMaps;

		graphics::IPainter* m_pPainter;
		graphics::IRenderer* m_pRenderer;

	public:
		DeviceWin32(const SDeviceParameters& Params);
		virtual ~DeviceWin32();

		virtual bool run();
		virtual void close();
		virtual void yield();
		virtual void sleep(u32 nTimeMs);

		virtual graphics::IPainter* createPainter(graphics::ePainterTypes eType, graphics::eColorFormat eFormat);
		virtual graphics::IRenderer* createRenderer();

		virtual void minimizeWindow();
		virtual void maximizeWindow();
		virtual void restoreWindow();

		virtual void setWindowCaption(const std::tstring& strCaption);

		virtual bool isWindowActive() const;
		virtual bool isWindowFocused() const;
		virtual bool isWindowMinimized() const;

		virtual graphics::IPainter* getPainter() const;
		virtual graphics::IRenderer* getRenderer() const;
		virtual eDeviceTypes getDeviceType() const;

		static LRESULT CALLBACK Procedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
		static DeviceWin32* getDeviceFromHWND(HWND hWnd);

	private:
		bool _createWindow();
	};

} // namespace device
} // namespace sol9